home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / aminet / comm / misc / xqsrc1_7.lzh / library / error.c < prev    next >
C/C++ Source or Header  |  1993-03-12  |  5KB  |  257 lines

  1. /*
  2.  *    Name:                error.c
  3.  *
  4.  * Description:    Error reporting functions for xferq.library
  5.  *
  6.  * Copyright:        1992-1993 by David Jones.
  7.  *
  8.  * Distribution:
  9.  *        This program is free software; you can redistribute it and/or modify
  10.  *        it under the terms of the GNU General Public License as published by
  11.  *        the Free Software Foundation; either version 2 of the License, or
  12.  *        (at your option) any later version.
  13.  *
  14.  *        This program is distributed in the hope that it will be useful,
  15.  *        but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  *        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  *        GNU General Public License for more details.
  18.  *
  19.  *        You should have received a copy of the GNU General Public License
  20.  *        along with this program; if not, write to:
  21.  *
  22.  *                The Free Software Foundation        David Jones
  23.  *                675 Mass Ave                            6730 Tooney Drive
  24.  *                Cambridge, MA                            Orleans, Ontario
  25.  *                02139                                        K1C 6R4
  26.  *                USA                                        Canada
  27.  *
  28.  *    Usenet:    gnu@prep.ai.mit.edu                    aa457@freenet.carleton.ca
  29.  *    Fidonet:                                                1:163/109.8
  30.  *
  31.  *        $Log: $
  32.  *
  33.  */
  34.  
  35. #include <exec/types.h>
  36. #include <exec/semaphores.h>
  37. #include <proto/exec.h>
  38. #include <proto/utility.h>
  39. #include "xferq.h"
  40. #include "xferqint.h"
  41. #include "xferq_pragmas.h"
  42. #include "execlists.h"
  43.  
  44.  
  45. #define    HT_SIZE        71
  46.  
  47. struct MinList ETable[HT_SIZE];
  48. extern struct SignalSemaphore ObjectLock;
  49.  
  50. char *ErrorMsgs[] = {
  51.     "Operation successful",
  52.     "Insufficient memory",
  53.     "Disk I/O error",
  54.     "End of queue detected",
  55.     "Required tag missing",
  56.     "Object is locked",
  57.     "Object does not exist",
  58.     "Bad address specification",
  59.     "No session in progress",
  60.     "Illegal use of object",
  61.     "Work already queued"
  62. };
  63.  
  64.  
  65. void InitErrors(void)
  66. /*
  67.  *    Does:    Initializes the ENode table upon opening the library.
  68.  */
  69. {
  70. int i;
  71.  
  72.     for (i = 0; i < HT_SIZE; i++) {
  73.         NEWLIST(&ETable[i]);
  74.     }
  75. }
  76.  
  77.  
  78. struct ENode *FindENode(BOOL create)
  79. /*
  80.  *    In:    create            TRUE to create ENode if not found.
  81.  *
  82.  *    Does:    Finds the ENode associated with the current process.  If one
  83.  *            cannot be found, it is created if requested.
  84.  */
  85. {
  86. struct ENode *en;
  87. struct Task *task;
  88. int hash;
  89.  
  90.     ObtainSemaphore(&ObjectLock);
  91.     task = FindTask(NULL);
  92.     hash = (ULONG)task % HT_SIZE;
  93.     en = FIRST(&ETable[hash]);
  94.     while (NEXT(en)) {
  95.         if (en->task == task) {
  96.             ReleaseSemaphore(&ObjectLock);
  97.             return en;
  98.         }
  99.         en = NEXT(en);
  100.     }
  101.     
  102.     en = NULL;
  103.     if (create) {
  104.         /*
  105.          *    We must use memobj's low level allocator since AllocObject
  106.          * calls Error() upon error, which calls FindENode...
  107.          */
  108.         en = AllocObject(sizeof(struct ENode), XQO_ENODE);
  109.         if (en) {
  110.             en->task = task;
  111.             en->error = XQERROR_OK;
  112.             en->flags = 0;
  113.             ADDHEAD(&ETable[hash], en);
  114.         }
  115.     }
  116.     ReleaseSemaphore(&ObjectLock);
  117.     return en;
  118. }
  119.  
  120.  
  121. void DropENode(struct ENode *en)
  122. /*
  123.  *    In:    en                    ENode to destroy.
  124.  *
  125.  * Does:    Removes and returns the ENode to the system.  This function
  126.  *            helps keep the ENode table clean.
  127.  */
  128. {
  129.  
  130.     ObtainSemaphore(&ObjectLock);
  131.     REMOVE(en);
  132.     FreeObject(en);
  133.     ReleaseSemaphore(&ObjectLock);
  134. }
  135.  
  136.  
  137. ULONG *PeekError(void)
  138. /*
  139.  *    Does:    Returns a pointer to the address where error codes should be
  140.  *            stored.
  141.  */
  142. {
  143. struct ENode *en;
  144.  
  145.     en = FindENode(TRUE);
  146.     if (en) {
  147.         return &en->error;
  148.     }
  149.     else {
  150.         return NULL;
  151.     }
  152. }
  153.  
  154.  
  155. void Error(long code)
  156. /*
  157.  *    In:    code                Error code to set
  158.  *
  159.  * Does:    Installs the error code in the ENode.
  160.  */
  161. {
  162. BOOL create;
  163. struct ENode *en;
  164.  
  165.     /*
  166.      * Prevent recursive loop if ENode can't be created due to lack
  167.      * of memory.
  168.      */
  169.     create = (code == XQERROR_NOMEM) ? FALSE : TRUE;
  170.     en = FindENode(create);
  171.     if (en) {
  172.         en->error = code;
  173.     }
  174. }
  175.  
  176.  
  177. void SetErrorTags(struct TagItem *tags)
  178. /*
  179.  *    In:    tags                Taglist passed to a tag function
  180.  *
  181.  * Does:    Searches for the tags XQ_ErrorCode and XQ_ErrorMsg and fills
  182.  *            in the data if found.
  183.  */
  184. {
  185. long code, *codeP;
  186. char **msgP;
  187. struct ENode *en;
  188.  
  189.     /*
  190.      * Get the error code.  If the ENode cannot be created, then treat
  191.      * the error as lack of memory.
  192.      */
  193.     en = FindENode(TRUE);
  194.     if (en) {
  195.         code = en->error;
  196.     }
  197.     else {
  198.         code = XQERROR_NOMEM;
  199.     }
  200.     
  201.     codeP = (long *)GetTagData(XQ_ErrorCode, NULL, tags);
  202.     msgP = (char **)GetTagData(XQ_ErrorMsg, NULL, tags);
  203.     
  204.     /*
  205.      * Stuff the code and message pointers if they exist.
  206.      */
  207.     if (codeP) {
  208.         *codeP = code;
  209.     }
  210.     if (msgP) {
  211.         *msgP = XfqErrorMsg(code);
  212.     }
  213.     
  214.     /*
  215.      * Clear the error code only if any tags were asked for.
  216.      */
  217.     if ((codeP || msgP) && en) {
  218.         en->error = XQERROR_OK;
  219.     }
  220. }
  221.  
  222.  
  223. LONG __saveds __asm LIBGetError(void)
  224. /*
  225.  *    Does:    Returns the error code and clears it.
  226.  */
  227. {
  228. struct ENode *en;
  229. long code;
  230.  
  231.     en = FindENode(TRUE);
  232.     if (en) {
  233.         code = en->error;
  234.         en->error = XQERROR_OK;
  235.     }
  236.     else {
  237.         code = XQERROR_NOMEM;
  238.     }
  239.     return code;
  240. }
  241.  
  242.  
  243. char *__saveds __asm LIBErrorMsg(register __d0 LONG error)
  244. /*
  245.  *    In:    error        D0        Error code returned by XfqGetError
  246.  *
  247.  * Does:    Returns a pointer to an error message associated with the
  248.  *            given error code.
  249.  */
  250. {
  251.  
  252.     return CopyString(ErrorMsgs[error]);
  253. }
  254.  
  255.  
  256.  
  257.